package com.xique.park.controller.client.web.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.xique.common.core.utils.AliossUtil;
import com.xique.common.core.utils.OrikaUtil;
import com.xique.common.core.utils.SecurityUtils;
import com.xique.common.core.utils.StringUtils;
import com.xique.common.core.web.controller.BaseController;
import com.xique.common.core.web.domain.AjaxResult;
import com.xique.common.core.web.page.TableDataInfo;
import com.xique.park.bean.domain.*;
import com.xique.park.bean.domain.client.ParkClient;
import com.xique.park.bean.vo.client.ClientInOutVo;
import com.xique.park.bean.vo.client.ClientMultCarsVo;
import com.xique.park.controller.client.web.bean.dto.ParkInOut;
import com.xique.park.controller.client.web.bean.request.ClientParkOnListRequest;
import com.xique.park.controller.client.web.bean.request.WebClientInOutRecordRequest;
import com.xique.park.controller.client.web.bean.request.WebClientMultCarListRequest;
import com.xique.park.controller.client.web.service.biz.service.IClientRecordBizService;
import com.xique.park.service.biz.service.IClientBizService;
import com.xique.park.service.service.*;
import com.xique.system.api.RemoteSystemDictService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author shd
 * @create 2021/7/28 17:21
 */
@RestController
@RequestMapping("/record")
public class ClientRecordController extends BaseController {

    @Autowired
    private IClientRecordBizService clientRecordBizService;

    @Autowired
    private IParkCarService parkCarService;

    @Autowired
    private IParkOnService parkOnService;

    @Autowired
    private IParkOutService parkOutService;

    @Autowired
    private AliossUtil aliossUtil;

    @Autowired
    private IParkClientService parkClientService;

    @Autowired
    private IParkInService parkInService;

    @Autowired
    private IClientBizService clientBizService;

    @Autowired
    private IParkCarMngtypeService parkCarMngtypeService;

    @Autowired
    private RemoteSystemDictService remoteSystemDictService;

    @Autowired
    private IUserService userService;

    /**
     * 在场记录
     *
     * @param request /
     * @return com.xique.common.core.web.domain.AjaxResult
     * @author shd
     * @date 2021/7/29 10:35
     */
    @GetMapping("/parkOn/list")
    @ApiOperation("在场记录")
    public AjaxResult parkOnList(@Validated ClientParkOnListRequest request) {
        return clientRecordBizService.getParkOnList(request);
    }

    @GetMapping("/multCar/list")
    @ApiOperation("多位多车记录")
    public AjaxResult multCarList(WebClientMultCarListRequest request) {
        ParkCar parkCar = OrikaUtil.convert(request, ParkCar.class);
        // 无查询条件，直接返回
        if (StringUtils.isEmpty(parkCar.getPlate())
                && StringUtils.isEmpty(parkCar.getSeatNo())
                && StringUtils.isEmpty(parkCar.getUserName())
                && StringUtils.isEmpty(parkCar.getPhone())
                && StringUtils.isEmpty(parkCar.getAddress())) {
            return AjaxResult.success(Collections.emptyList());
        }

        // 查询匹配的车辆列表
        parkCar.setParkId(SecurityUtils.getParkId());
        List<ParkCar> parkCarList = parkCarService.selectParkCarList(parkCar);

        if (CollectionUtil.isNotEmpty(parkCarList)) {
            List<Long> userIds = parkCarList.stream().map(ParkCar::getParkUserId).distinct().collect(Collectors.toList());
            List<User> userList = userService.selectByIds(userIds);
            Map<Long, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, v -> v));

            for (ParkCar car : parkCarList) {
                if (ObjectUtil.isNotEmpty(userMap.get(car.getParkUserId()))) {
                    User user = userMap.get(car.getParkUserId());
                    car.setUserName(user.getUserName());
                    car.setPhone(user.getPhone());
                }

                List<ParkOn> parkOnList = new ArrayList<>();
                // 多位多车在场车辆数
                int onCarCnt = 0;

                if (StrUtil.isNotBlank(car.getBindPlates())) {
                    // 车辆数
                    car.setCarConts(car.getBindPlates().split(",").length);
                    for (String plate : car.getBindPlates().split(",")) {
                        // 查询车牌的在场信息
                        ParkOn parkOn = new ParkOn();
                        parkOn.setPlate(plate);
                        parkOn.setParkId(parkCar.getParkId());
                        List<ParkOn> tempParkOnList = parkOnService.selectParkOnByPlate(parkCar.getParkId(), plate);
                        if (CollectionUtil.isNotEmpty(tempParkOnList)) {
                            ParkOn parkOnInDb = tempParkOnList.get(0);
                            if (null != parkOnInDb) {
                                parkOnInDb.setIsOn("Y");
                                parkOnInDb.setOutStatusLabel(remoteSystemDictService.getDictLabel("car_pass_status",
                                        parkOnInDb.getInStatusLabel()).getData());
                                parkOnInDb.setInPic(aliossUtil.getJzyGetObjectUrl(parkOnInDb.getInPic()).toString());
                                // 在场记录
                                parkOnList.add(parkOnInDb);
                                onCarCnt += 1;
                            }
                        } else {
                            // 没有在场记录，查询该车辆在该车场最近一次出场时间
                            ParkOut search = new ParkOut();
                            search.setParkId(parkCar.getParkId());
                            search.setOutCarPlate(plate);
                            List<ParkOut> parkOutList = parkOutService.getParkOutList(search);
                            if (CollectionUtil.isNotEmpty(parkOutList)) {
                                ParkOut recentParkOut = parkOutList.get(0);
                                if (null != recentParkOut) {
                                    parkOn.setOutLaneName(recentParkOut.getOutLaneName());
                                    parkOn.setOutPic(aliossUtil.getJzyGetObjectUrl(recentParkOut.getOutPic()).toString());
                                    parkOn.setOutStatusLabel(remoteSystemDictService.getDictLabel("car_pass_status",
                                            recentParkOut.getStatus()).getData());
                                    parkOn.setOutTime(recentParkOut.getOutTime());
                                }
                            }
                            parkOn.setIsOn("N");
                            parkOnList.add(parkOn);
                        }
                    }
                }
                car.setParkOnList(parkOnList);
                car.setOnCarCount(onCarCnt);
                int remainSpaceCount = (null != car.getSpaces()) ? (car.getSpaces() - car.getOnCarCount()) : 0;
                car.setRemainSpaceCount(Math.max(0, remainSpaceCount));
            }
        }

        TableDataInfo dataTable = getDataTable(parkCarList);
        dataTable.setRows(OrikaUtil.converts(parkCarList, ClientMultCarsVo.class));
        return new AjaxResult(dataTable);
    }

    @GetMapping("/inOut/list")
    @ApiOperation("出入场记录")
    public AjaxResult clientInOnList(WebClientInOutRecordRequest request) {
        request.setClientId(String.valueOf(SecurityUtils.getClientId()));
        request.setOrderByColumn("id");
        request.setIsAsc("desc");
        if (StringUtils.isEmpty(request.getClientId())) {
            return AjaxResult.success(new ArrayList<>());
        }

        // 搜索条件封装
        ParkClient parkClient = parkClientService.selectParkClientById(Long.valueOf(request.getClientId()));
        ParkIn search = OrikaUtil.convert(request, ParkIn.class);
        search.setParkId(parkClient.getParkId());
        search.setInCarPlate(request.getPlate());

        PageHelper.startPage(request.getPageNum(), request.getPageSize(), "in_time" + " " + "desc");

        List<ParkInOut> parkInOuts = parkInService.selectParkInOutList(search);

        List<Long> mngTypeIds = parkInOuts.stream().map(ParkInOut::getInMngTypeId).distinct().collect(Collectors.toList());
        ParkCarMngtype parkCarMngtypeSearch = new ParkCarMngtype();
        parkCarMngtypeSearch.setMngTypeIds(mngTypeIds);
        List<ParkCarMngtype> mngtypeList = parkCarMngtypeService.selectParkCarMngtypeList(parkCarMngtypeSearch);
        Map<Long, String> mngtypeMap = mngtypeList.stream().collect(Collectors.toMap(ParkCarMngtype::getId, ParkCarMngtype::getName));
        parkInOuts.forEach(item -> {
            if (StringUtils.isNotEmpty(mngtypeMap.get(item.getInMngTypeId()))) {
                item.setInMngTypeName(mngtypeMap.get(item.getInMngTypeId()));
            }
        });

        TableDataInfo dataTable = getDataTable(parkInOuts);
        // bean映射 & 字典转义
        List<ClientInOutVo> clientInOutVos = clientBizService.convertParkInoutToVo(parkInOuts);
        dataTable.setRows(clientInOutVos);
        return new AjaxResult(dataTable);
    }
}
